package cn.hxth.dubbo.service.impl;

import cn.hxth.api.model.Consumer;
import cn.hxth.api.model.OutstockRecord;
import cn.hxth.api.model.ProductBaseInfo;
import cn.hxth.api.model.Remind;
import cn.hxth.api.query.OutstockRecordQueryObject;
import cn.hxth.api.query.PageResult;
import cn.hxth.api.query.QueryObject;
import cn.hxth.api.service.IOutstockRecordService;
import cn.hxth.api.util.SplitUtil;
import cn.hxth.dubbo.service.mapper.OutstockRecordMapper;
import cn.hxth.dubbo.service.mapper.ProductMapper;
import cn.hxth.dubbo.service.mapper.RemindMapper;
import cn.hxth.dubbo.service.mq.RabbitMQSender;
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Transactional
@Service
public class OutstockRecordServiceImpl implements IOutstockRecordService {
    @Resource
    private RemindMapper remindMapper ;
    @Resource(name = "myRedisTemplate")
    private RedisTemplate<String,Object> redisTemplate ;
    @Resource
    private RestTemplate restTemplate ;
    @Resource
    private OutstockRecordMapper outstockRecordMapper;
    @Resource
    private ProductMapper productMapper ;
    @Resource
    private RabbitMQSender rabbitMQSender ;
    @Override
    public boolean insertOutstockRecord(List<OutstockRecord> outstockRecordList) {
        for(OutstockRecord outstockRecord:outstockRecordList){
            // 判断出库数量是否超出现有库存
            if(outstockRecord.getInventory() < outstockRecord.getOutcount()){
                throw new RuntimeException("规格为:"+outstockRecord.getProductSpec()+"的"+outstockRecord.getProductName()+"出库数量超出现有库存") ;

            }
        }
        boolean flag = this.outstockRecordMapper.insertList(outstockRecordList);
        if (flag) {
            // 如果数据出现变动则删除redis中的统计信息数据
            this.redisTemplate.delete("out_aggr");
            // 为此次出库之后所要修改其他表信息填充相关数据
            for (OutstockRecord outstockRecord : outstockRecordList) {

                ProductBaseInfo productBaseInfo = new ProductBaseInfo();
                productBaseInfo.setInventory(outstockRecord.getInventory());
               productBaseInfo.setLin(outstockRecord.getLin());
                productBaseInfo.setPrice(outstockRecord.getPrice());
                productBaseInfo.setPid(outstockRecord.getProduct().getPid());
                int inventory = productBaseInfo.getInventory() -outstockRecord.getOutcount();
                System.out.println(productBaseInfo.getInventory());
                productBaseInfo.setInventory(inventory);
                Consumer consumer = outstockRecord.getConsumer() ;
                consumer.setTotal(outstockRecord.getTotalPrice());
                // 发送一条更新购货单位消费总额的消息
                this.rabbitMQSender.send("data-change-queue", "{\"event_type\": \"updateTotal\",\"data\":" + JSONObject.toJSONString(consumer) + "}");
                /*try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
                // 发送一条更新商品库存的消息
                this.rabbitMQSender.send("data-change-queue", "{\"event_type\": \"updateProductBaseInfo\",\"data\": " + JSONObject.toJSONString(productBaseInfo) + "}");



                // 如果该商品库存数已到警戒线则产生警戒记录
                if(inventory<=outstockRecord.getProduct().getFloor()){
                    Remind remind = new Remind() ;
                    remind.setCount(productBaseInfo.getInventory());
                    remind.setSpec(outstockRecord.getProduct().getSpec());
                    remind.setFloor(outstockRecord.getProduct().getFloor());
                    remind.setProductSpec(outstockRecord.getProductSpec());
                    remind.setProductName(outstockRecord.getProductName());


                    //如果该商品已经在警戒列表里
                    if(this.remindMapper.selectCountBySid(outstockRecord.getProduct().getSpec().getSid())>0){
                        // 发送数据更新消息
                        this.rabbitMQSender.send("data-change-queue","{\"event_type\": \"updateRemindCount\",  \"data\": " +JSONObject.toJSONString(remind) +   "}");

                    }
                    else{
                        // 发送数据添加消息
                        this.rabbitMQSender.send("data-change-queue","{\"event_type\": \"insertRemind\",  \"data\": " +JSONObject.toJSONString(remind) +   "}");

                    }

                }}
        }
        else {
            throw new RuntimeException("系统未知问题") ;
        }


        return  flag ;
    }

    @Override
    public OutstockRecord getOutstockRecord(long ono) {
        OutstockRecord outstockRecord = null ;
        String jsonStr = (String) this.redisTemplate.opsForValue().get("outstockRecor_"+ono);
        if(jsonStr==null) {
            outstockRecord = this.outstockRecordMapper.selectByPrimaryKey(ono);
            this.redisTemplate.opsForValue().set("outstockRecor_"+ono,outstockRecord);
        }
       else{
           outstockRecord = JSONObject.parseObject(jsonStr,OutstockRecord.class) ;
        }
        return outstockRecord ;
    }

    @Override
    public PageResult findAll(OutstockRecordQueryObject outstockRecordQueryObject) {
          /*
        List<InstockRecord> instockRecordLIst = new ArrayList<>() ;

      Set<String> keys = redisTemplate.keys("instockRecordList_*");
        for(String key:keys){
            long saveTime = Long.parseLong(key.split("_")[1]);

            long firstTime = instockRecordQueryObject.getFirstDate().getTime() ;
            long secondTime = instockRecordQueryObject.getSecondDate().getTime() ;
            if(firstTime<=saveTime&&secondTime>=saveTime){
                String jsonStr = (String) this.redisTemplate.opsForValue().get(key);
                List<InstockRecord> instockRecords = JSONArray.parseArray(jsonStr, InstockRecord.class);
                instockRecordLIst.addAll(instockRecordLIst) ;
            }
        }*/

        int count = this.outstockRecordMapper.selectCount(outstockRecordQueryObject) ;
        List<Integer> onos = this.outstockRecordMapper.selectOnoForCache(outstockRecordQueryObject) ;
        List<OutstockRecord> listData = new ArrayList<>() ;
        for(int ono:onos){
            OutstockRecord outstockRecord = null ;
            String jsonStr = (String) this.redisTemplate.opsForValue().get("outstockRecor_" + ono);
            if(jsonStr==null){
                outstockRecord = this.outstockRecordMapper.selectByPrimaryKey(ono);
                this.redisTemplate.opsForValue().set("outstockRecor_"+ono,JSONObject.toJSONString(outstockRecord));
            }
            else{
                outstockRecord = JSONObject.parseObject(jsonStr,OutstockRecord.class) ;
            }
            listData.add(outstockRecord) ;

        }
       // List<OutstockRecord> listData = this.outstockRecordMapper.selectAll(outstockRecordQueryObject);
        return  new PageResult(listData,count,outstockRecordQueryObject.getCurrentPage(),outstockRecordQueryObject.getPageSize()) ;

    }

    @Override
    public PageResult findAggrInfo(QueryObject queryObject) {
        // 用于读取redis缓存列表的的起始下标
        int start = (queryObject.getCurrentPage()-1)*queryObject.getPageSize() ;
        // 用于读取redis缓存列表的结束下标
        int end = start+queryObject.getPageSize()-1 ;
        // 查询数据库出库统计记录数
        Integer count = this.outstockRecordMapper.selectAggrInfoCount();
        // 从redis中获取出库统计数据
        List<Object> outaggrList =  this.redisTemplate.opsForHash().values("out_aggr") ;
        if(outaggrList.size()>0){
           List<Object> listData = SplitUtil.splitList(outaggrList, queryObject.getCurrentPage(), queryObject.getPageSize());
           return new PageResult(listData,count,queryObject.getCurrentPage(),queryObject.getPageSize()) ;
        }
        // 查询全部出库统计数据
        List<Map<String, Object>> allData = this.outstockRecordMapper.selectAggrInfo() ;
        // 将数据写入redis
        this.redisTemplate.opsForList().leftPushAll("out_aggr",allData) ;
        // 从redis读取分页数据
        outaggrList =  this.redisTemplate.opsForList().range("out_aggr",start,end) ;
        /*List<Map<String, Object>> listData = this.outstockRecordMapper.selectAggrInfoSplit(queryObject);*/
        return  new PageResult(outaggrList,count,queryObject.getCurrentPage(),queryObject.getPageSize()) ;
    }
}
